package com.jzo2o.orders.manager.service.client;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.jzo2o.api.market.CouponApi;
import com.jzo2o.api.market.dto.request.CouponUseReqDTO;
import com.jzo2o.api.market.dto.response.AvailableCouponsResDTO;
import com.jzo2o.api.market.dto.response.CouponUseResDTO;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;

@Component
@Slf4j
public class MarketClient {

    @Resource
    private CouponApi couponApi;

    /**
     * @param totalAmount 总金额
     * @return 优惠券列表
     */
    @SentinelResource(value = "getAvailableCoupons",fallback = "getAvailableCouponsFallback",
            blockHandler = "getAvailableCouponsBlockHandler")
    public List<AvailableCouponsResDTO> getAvailableCoupons(BigDecimal totalAmount){
        return couponApi.getAvailable(totalAmount);
    }

    public List<AvailableCouponsResDTO> getAvailableCouponsFallback(BigDecimal totalAmount, Throwable t){
        log.error("远程调用出现异常，执行降级方法。totalAmount={}", totalAmount, t);
        return Collections.emptyList();
    }

    public List<AvailableCouponsResDTO> getAvailableCouponsBlockHandler(BigDecimal totalAmount, BlockException e){
        log.error("触发限流熔断，执行降级方法。totalAmount={}", totalAmount, e);
        return Collections.emptyList();
    }

    @SentinelResource(value = "useCoupon", fallback = "useCouponFallback", blockHandler = "useCouponBlockHandler")
    public CouponUseResDTO useCoupon(CouponUseReqDTO dto){
        return couponApi.use(dto);
    }

    public CouponUseResDTO useCouponFallback(CouponUseReqDTO dto, Throwable t){
        log.error("远程调用出现异常，执行降级方法。参数：{}", dto, t);
        return null;
    }

    public CouponUseResDTO useCouponBlockHandler(CouponUseReqDTO dto, BlockException e){
        log.error("触发限流熔断，执行降级方法。参数：{}", dto, e);
        return null;
    }
}
